/**
 * 版权 (c) 2013 意定达科技有限公司
 * 保留所有权利。
 */
package cn.lunatic.db;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.log4j.Logger;
import org.jdom.Element;

import cn.lunatic.pub.DataMap;
import cn.lunatic.xmlpares.JdomXMLUtil;

/**
 * @Description:
 * @author ganfeng
 * @date 2014-3-10 下午01:39:43
 */
public class DBSource {
	private final static Logger logger = Logger.getLogger(DBSource.class);// 获取
	
	public final static String LUNATIC_DAO_DATA_SOURCE_EXP = "/lunatic/dao/dataSource[@id='dbSource']";

	private BasicDataSource dataSource;
	
	private int maxRecord;//查询的最大记录数
	private int timeOut;//查询超时
	
	
	public DBSource(Element dbElement){
		initDataSource(dbElement);
	}
	
	/**
	 * 
	 * @Description:获取数据库连接
	 * @author ganfeng
	 * @date 2014-3-10 下午01:42:10
	 * @return
	 */
	public Connection getConn(){
		return getConn(false);
	}
	
	/**
	 * 
	 * @Description:获取数据库连接
	 * @author ganfeng
	 * @date 2014-3-10 下午01:41:18
	 * @param autoCommit是否自动提交事务
	 * @return
	 */
	public Connection getConn(boolean autoCommit) {
		Connection con = null;
		if (dataSource != null) {
			try {
				con = dataSource.getConnection();
				con.setAutoCommit(autoCommit);
			} catch (Exception e) {
				logger.info("获取数据库连接失败...");
			}
		}
		return con;
	}

	/**
	 * 
	 * @Description:初始化数据源
	 * @author ganfeng
	 * @date 2014-3-10 下午12:23:01
	 * @param connectURI
	 * @param username
	 * @param password
	 * @param driverClass
	 * @param initialSize
	 *            连接池启动时创建的初始化连接数量（默认值为0）
	 * @param maxActive
	 *            连接池的最大数据库连接数。设为0表示无限制。
	 * @param minIdle
	 *            连接池中最小的空闲的连接数，低于这个数量会被创建新的连接（默认为0，调整为5，该参数越接近maxIdle，性能越好，因为连接的创建和销毁
	 *            ，都是需要消耗资源的；但是不能太大，因为在机器很空闲的时候，也会创建低于minidle个数的连接，
	 *            类似于jvm参数中的Xmn设置）
	 * @param maxIdle
	 *            最大空闲数，数据库连接的最大空闲时间。超过空闲时间，数据库连接将被标记为不可用，然后被释放。设为0表示无限制。
	 * @param maxWait
	 *            最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
	 */
	private void initDataSource(String driverClass, String connectURI, String username, String password,
			int initialSize, int maxActive,int minIdle, int maxIdle,
			int maxWait) {
		dataSource = new BasicDataSource();
		
		dataSource.setDriverClassName(driverClass);
		dataSource.setUrl(connectURI);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		
		dataSource.setInitialSize(initialSize); // 初始的连接数；
		dataSource.setMaxActive(maxActive);
		dataSource.setMinIdle(minIdle);
		dataSource.setMaxIdle(maxIdle);
		dataSource.setMaxWait(maxWait);
		

	}
	
	/**
	 * 
	 * @Description:通过数据源的配置文件获取数据库连接池配置信息并初始化数据源
	 * @author ganfeng
	 * @date 2014-3-10 下午02:08:45
	 * @param dbElement
	 * @return
	 */
	private void initDataSource(Element dbElement){
		String driverClass = JdomXMLUtil.getChildValue(dbElement, "driverClass");
		String connectURI = JdomXMLUtil.getChildValue(dbElement, "connectURI");
		String username = JdomXMLUtil.getChildValue(dbElement, "username");
		String password = JdomXMLUtil.getChildValue(dbElement, "password");
		
		int initialSize = Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "initialSize"));
		int maxActive = Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "maxActive"));
		int minIdle = Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "minIdle"));
		int maxIdle = Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "maxIdle"));
		int maxWait = Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "maxWait"));
		//最大查询记录数
		setMaxRecord(Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "maxRecord")));
		setTimeOut(Integer.valueOf(JdomXMLUtil.getChildValue(dbElement, "timeOut")));
		
		initDataSource(driverClass, connectURI, username, password, initialSize, maxActive, minIdle, maxIdle, maxWait);
	}
	
	/**
	 * 
	 * @Description:获取当前数据源状态：当前连接数(curr_active_num),当前空闲数()
	 * @author ganfeng
	 * @date 2014-3-10 下午02:42:59
	 * @return
	 */
	public DataMap getDataSourceStatus() {
		DataMap map = new DataMap();
		map.add("curr_active_num", dataSource.getNumActive());
		map.add("curr_idle_num", dataSource.getNumIdle());
		return map;
	}
	
	/**
	 * 
	 * @Description:关闭数据源
	 * @author ganfeng
	 * @date 2014-3-10 下午02:44:44
	 */
	public void shutDownDataSource(){
		try {
			dataSource.close();
		} catch (SQLException e) {
			logger.info("关闭数据源出错！",e);
		}
	}

	/**
	 * @return the maxRecord
	 */
	public int getMaxRecord() {
		return maxRecord;
	}

	/**
	 * @param maxRecord the maxRecord to set
	 */
	public void setMaxRecord(int maxRecord) {
		this.maxRecord = maxRecord;
	}

	/**
	 * @Description:
	 * @author ganfeng
	 * @date 2014-3-10 下午04:21:07
	 * @return
	 */
	public int getTimeOut() {
		return timeOut;
	}

	/**
	 * @param timeOut the timeOut to set
	 */
	public void setTimeOut(int timeOut) {
		this.timeOut = timeOut;
	}
	
	
}
